import 'dart:async';
import 'dart:convert';

import 'package:flutter/services.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:get/get.dart';
import 'package:thingskit/utils/ToastController.dart';
import 'package:usb_serial/usb_serial.dart';

class UsbController extends GetxController {
  var isDown = false.obs;
  var isDebugging = false.obs;
  var Lights = [].obs;
  var isSearching = false;
  var isSelectedAddress = ''.obs;
  Map<int, bool> versionMap = {};
  StreamSubscription<Uint8List>? _subscription;
  StreamSubscription<UsbEvent>? _usbEventSubscription;
  UsbPort? _port;
  ToastController toastController = Get.put(ToastController());

  @override
  void onClose() {
    _subscription?.cancel();
    _usbEventSubscription?.cancel();
    _port?.close();
    super.onClose();
  }

  void turnOver() {
    if (isDown.value) {
      SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
    } else {
      SystemChrome.setPreferredOrientations([DeviceOrientation.portraitDown]);
    }
    isDown.value = !isDown.value;
  }

  Future<void> openSerialPortDebug() async {
    isDebugging.value = !isDebugging.value;
    if (isDebugging.value) {
      try {
        // 1. 获取USB设备列表
        List<UsbDevice> devices = await UsbSerial.listDevices();
        if (devices.isEmpty) {
          print("未找到USB设备");
          toastController.showCenterToast('未找到串口设备');
          closeSerialPortDebug();
          return;
        }
        // 2. 选择第一个设备并连接
        UsbDevice device = devices.first;
        _port = await device.create();
        if (!await _port!.open()) {
          print('连接失败');
          closeSerialPortDebug();
          return;
        }
        // 3. 配置串口参数
        await _port!
          ..setDTR(true)
          ..setRTS(true)
          ..setPortParameters(
            57600,
            UsbPort.DATABITS_8,
            UsbPort.STOPBITS_1,
            UsbPort.PARITY_NONE,
          );
        //4. 监听数据变化
        isDebugging.value = true;
        _subscription = _port!.inputStream!.listen(_handleReceivedData);

        //5. 监听设备断开事件
        _usbEventSubscription = UsbSerial.usbEventStream?.listen((event) {
          if (event.event == UsbEvent.ACTION_USB_DETACHED) {
            print("设备拔出");
            toastController.showCenterToast('设备已拔出');
            closeSerialPortDebug();
          }
        });
      } catch (e) {
        print('数据解析失败: $e');
        await closeSerialPortDebug();
      }
    } else {
      await closeSerialPortDebug();
    }
  }

  void _handleReceivedData(Uint8List data) {
    final response = String.fromCharCodes(data);
    print("拿到的数据是: $response");
    response.split('\n').forEach((item) {
      if (item.isNotEmpty) {
        try {
          Map<String, dynamic> jsonData = jsonDecode(item);
          if (jsonData.containsKey('cmd')) {
            switch (jsonData['cmd']) {
              case "searchLight":
                print('解析到的灯json为：$jsonData');
                _storeToLights(jsonData);
                break;
              case "search_new_light":
                print('解析到的新灯json为：$jsonData');
                _storeToLights(jsonData);
                break;
              case "search_info":
                print('查看灯的json为：$jsonData');
                showLightInfo(jsonData);
                break;
              default:
                break;
            }
          }
        } catch (e) {
          print('数据解析失败-----: $e');
        }
      }
    });
  }

  void _storeToLights(Map<String, dynamic> jsonData) {
    if (jsonData['addr'] != null) {
      bool isNewDevice = true;
      for (var light in Lights) {
        if (light['addr'] == jsonData['addr']) {
          isNewDevice = false;
          break;
        }
      }
      if (isNewDevice) {
        Lights.add(jsonData);
      }
    }
  }

  Future<void> closeSerialPortDebug() async {
    await _subscription?.cancel();
    await _usbEventSubscription?.cancel();
    await _port?.close();
    _usbEventSubscription = null;
    _subscription = null;
    _port = null;
    isDebugging.value = false;
    print("连接已断开");
  }

  int getNowTime() {
    // ~/ 整除运算
    return DateTime.now().millisecondsSinceEpoch ~/ 1000;
  }

  Future<int> sendCommand(Map<String, dynamic> command) async {
    if (!isDebugging.value) {
      toastController.showCenterToast('串口未打开，无法发送数据');
      return 0;
    }
    int nowTime = getNowTime();

    //串口不能发送16的倍数的字符，加上这个，把发送的数据限定在奇数
    try {
      command['version'] = nowTime;
      String dataString = jsonEncode(command);
      if (dataString.length % 2 == 0) {
        command['t'] = '12';
      }
      String commandStr = jsonEncode(command);
      print('发送的指令是：$commandStr');
      _port!.write(Uint8List.fromList(commandStr.codeUnits));
    } catch (e) {
      print('发送失败$e');
    }
    return nowTime;
  }

  // 搜灯
  Future<int> searchLight() async {
    Lights.clear();
    Map<String, dynamic> command = {'cmd': 'searchLight'};
    return await sendCommand(command);
  }

  //只搜新灯
  Future<int> searchNewLight() async {
    Lights.clear();
    Map<String, dynamic> command = {'cmd': 'search_new_light'};
    return await sendCommand(command);
  }

  //单灯闪一闪
  Future<int> flash(String? address) async {
    if (address == null) {
      toastController.showCenterToast('请选择一个灯');
      return 0;
    }
    Map<String, dynamic> command = {'cmd': 'blink', 'addr': address};
    return await sendCommand(command);
  }

  //单灯停止闪
  Future<int> stopFlash(String? address) async {
    if (address == null) {
      toastController.showCenterToast('请选择一个灯');
      return 0;
    }
    Map<String, dynamic> command = {'cmd': 'stop_blink', 'addr': address};
    return await sendCommand(command);
  }

  //单灯邀请入组
  Future<int> inviteGroup(String? address) async {
    if (address == null) {
      toastController.showCenterToast('请选择一个灯');
      return 0;
    }
    Map<String, dynamic> command = {'cmd': 'invite_group', 'addr': address};
    return await sendCommand(command);
  }

  //单灯取消入组
  Future<int> unInviteGroup(String? address) async {
    if (address == null) {
      toastController.showCenterToast('请选择一个灯');
      return 0;
    }
    Map<String, dynamic> command = {'cmd': 'cancel_one_group', 'addr': address};
    return await sendCommand(command);
  }

  // 单灯获取灯消息
  Future<int> lightInfo(String? address) async {
    if(!isDebugging.value){
      toastController.showCenterToast('串口未打开，无法发送数据');
      return 0;
    }
    EasyLoading.show(
      status: '加载中...',
      maskType: EasyLoadingMaskType.black,
      dismissOnTap: true,
    );
    if (address == null) {
      return 0;
    }
    Map<String, dynamic> command = {'cmd': 'search_info', 'addr': address};
    isSearching = true;
    int version = await sendCommand(command);
    versionMap[version] = true;
    return version;
  }

  // 单灯获取灯消息渲染函数
  void showLightInfo(Map<String, dynamic> info) {
    if (!EasyLoading.isShow || versionMap[info['version']] == false) {
      return;
    }
    if (isSearching) {
      EasyLoading.dismiss();
      versionMap[info['version']] = false;
      toastController.showInfo(info);
      isSearching = false;
    }
  }

  // 下发入组
  Future<int> sendGroup(String groupId) async {
    Map<String, dynamic> command = {
      'cmd': 'enter_group',
      'group_id': int.tryParse(groupId) ?? 0,
    };
    return await sendCommand(command);
  }

  //取消所有邀请入组
  Future<int> cancelAllGroupInvite() async {
    Map<String, dynamic> command = {'cmd': 'cancel_all_group'};
    return await sendCommand(command);
  }

  //下发单灯配置
  Future<int> setConfigDevice(
    String address,
    Map<String, dynamic> config,
  ) async {
    Map<String, dynamic> command = {
      'cmd': 'set_device',
      'addr': address,
      ...config,
    };
    return await sendCommand(command);
  }

  //下发组别配置
  Future<int> setGroupDevice(
    String groupId,
    Map<String, dynamic> groupConfig,
  ) async {
    Map<String, dynamic> command = {
      'cmd': 'set_group_device',
      'old_group': int.tryParse(groupId) ?? 0,
      'group_id': int.tryParse(groupId) ?? 0,
      ...groupConfig,
    };
    return await sendCommand(command);
  }

  //下发组别自动模式
  Future<int> setModeAutoGroup(String groupId) async {
    Map<String, dynamic> command = {
      'cmd': 'set_group_mode_auto',
      'group_id': int.tryParse(groupId) ?? 0,
    };
    return await sendCommand(command);
  }

  //下发单灯自动模式
  Future<int> setModeAutoDevice(String address) async {
    Map<String, dynamic> command = {
      'cmd': 'set_device_mode_auto',
      'addr': address,
    };
    return await sendCommand(command);
  }

  // 组别闪一闪
  Future<int> flashGroup(String groupId) async {
    Map<String, dynamic> command = {
      'cmd': 'blink_group',
      'group_id': int.tryParse(groupId) ?? 0,
    };
    return await sendCommand(command);
  }

  // 组别停止闪
  Future<int> stopFlashGroup(String groupId) async {
    Map<String, dynamic> command = {
      'cmd': 'stop_blink_group',
      'group_id': int.tryParse(groupId) ?? 0,
    };
    return await sendCommand(command);
  }

  //组别 常亮
  Future<int> alwaysFlashGroup(String groupId) async {
    Map<String, dynamic> command = {
      'cmd': 'set_group_device',
      'group_id': int.tryParse(groupId) ?? 0,
      'mode': 1,
      "fixedBrightness": 100,
      "lightmode_setting": 1,
      "group_setting": 0,
      "rf_setting": 0,
    };
    return await sendCommand(command);
  }

  //单灯常亮
  Future<int> alwaysFlashLight(String address) async {
    Map<String, dynamic> command = {
      'cmd': 'set_device',
      'addr': address,
      'mode': 1,
      "fixedBrightness": 100,
      "lightmode_setting": 1,
      "group_setting": 0,
      "rf_setting": 0,
    };
    return await sendCommand(command);
  }

  //组别 常灭
  Future<int> closeFlashGroup(String groupId) async {
    Map<String, dynamic> command = {
      'cmd': 'set_group_device',
      'group_id': int.tryParse(groupId) ?? 0,
      'mode': 1,
      "fixedBrightness": 0,
      "lightmode_setting": 1,
      "group_setting": 0,
      "rf_setting": 0,
    };
    return await sendCommand(command);
  }

  //单灯 关灯
  Future<int> closeFlashLight(String address) async {
    Map<String, dynamic> command = {
      'cmd': 'set_device',
      'addr': address,
      'mode': 1,
      "fixedBrightness": 0,
      "lightmode_setting": 1,
      "group_setting": 0,
      "rf_setting": 0,
    };
    return await sendCommand(command);
  }

  //下发组别亮度
  Future<int> sendBrightnessGroup(String groupId, int brightness) async {
    Map<String, dynamic> command = {
      'cmd': 'set_group_device',
      'group_id': int.tryParse(groupId) ?? 0,
      'mode': 1,
      "fixedBrightness": brightness,
      "lightmode_setting": 1,
      "group_setting": 0,
      "rf_setting": 0,
    };
    return await sendCommand(command);
  }

  //下发单灯亮度
  Future<int> sendBrightnessLight(String address, int brightness) async {
    Map<String, dynamic> command = {
      'cmd': 'set_device',
      'addr': address,
      'mode': 1,
      "fixedBrightness": brightness,
      "lightmode_setting": 1,
      "group_setting": 0,
      "rf_setting": 0,
    };
    return await sendCommand(command);
  }



}
